import Constants from "../Constants/Constants";
import Oriented from "../Constants/Oriented";

/**
 * 一些通用的换算公式
 * created by Five on 2018-11-7 15:13:17
 */

export default class CalcHelper {
    private _mapSize: cc.Size = cc.Size.ZERO;
    public RunningMapSize(size: cc.Size) {
        this._mapSize = size;
    }

    /**
     * 坐标转换为格子索引
     * 需要根据屏幕的实际尺寸进行一次换算
     * @param pos 位置
     * @param mapSize 地图大小
     * @return 索引
     */
    public PositionToLocation(pos: cc.Vec2, mapSize: cc.Size = this._mapSize): number {
        let xCount = Math.floor(mapSize.width / Constants.ENTITY_EDGE);

        let newPos = pos.add(cc.v2(Constants.ENTITY_EDGE / 2, Constants.ENTITY_EDGE / 2));
        let cPos = new cc.Vec2;
        cc.Camera.main.getCameraToWorldPoint(newPos, cPos);

        let x = Math.floor(cPos.x / Constants.ENTITY_EDGE);
        let y = Math.floor(cPos.y / Constants.ENTITY_EDGE);
        return y * xCount + x;
    }

    /**
     * 索引转换为坐标
     * 由于所有的块都是以中心为原点,而计算出来的是左下角的位置
     * 所以在返回时需要加上块的半宽半高
     * @param loc 索引
     * @param mapSize 地图大小
     * @return cc.Vec2
     */
    public LocationToPostion(loc: number, mapSize: cc.Size = this._mapSize) {
        if (mapSize == null)
            mapSize = this._mapSize;

        let xCount = Math.floor(mapSize.width / Constants.ENTITY_EDGE);

        let x = Math.floor(loc % xCount);
        let y = Math.floor(loc / xCount);
        return new cc.Vec2(x * Constants.ENTITY_EDGE, y * Constants.ENTITY_EDGE);
    }

    public Distance(pA: cc.Vec2, pB: cc.Vec2): number {
        let xLen = Math.pow((pA.x - pB.x), 2);
        let yLen = Math.pow((pA.y - pB.y), 2);
        return Math.sqrt(xLen + yLen);
    }

    /**
     * forward up 玩家
     * @param current 
     * @param ori 
     */
    public FU(current: cc.Vec2, ori: Oriented): cc.Vec2 {
        let affix = ori == Oriented.LEFT ? -Constants.ENTITY_EDGE / 2 : Constants.ENTITY_EDGE / 2;
        return current.add(cc.v2(affix, Constants.ENTITY_EDGE / 2));
    }

    /**
     * forward
     * @param current 
     * @param ori 
     */
    public FW(current: cc.Vec2, ori: Oriented): cc.Vec2 {
        let affix = ori == Oriented.LEFT ? -5 : 5;
        return current.add(cc.v2(affix, 5));
    }

    /**
     * forward down
     * @param current 
     * @param ori 
     */
    public FD(current: cc.Vec2, ori: Oriented): cc.Vec2 {
        let affix = ori == Oriented.LEFT ? -5 : 5;
        return current.add(cc.v2(affix, -Constants.ENTITY_EDGE + 5));
    }

    /**
     * Down
     * @param current 
     * @param ori 
     */
    public DO(current: cc.Vec2, ori: Oriented): cc.Vec2 {
        let affix = ori == Oriented.LEFT ? 5 : -5;
        return current.add(cc.v2(affix, -Constants.ENTITY_EDGE + 5));
    }

    /**
     * Down Close
     * @param current 
     * @param ori 
     */
    public DC(current: cc.Vec2, ori: Oriented): cc.Vec2 {
        let affix = ori == Oriented.LEFT ? 5 : -5;
        return current.add(cc.v2(affix, -Constants.ENTITY_EDGE / 2 + 5));
    }

    /**
     * UpORDown
     * @param current 
     * @param ori 
     */
    public UD(current: cc.Vec2, ori: Oriented): cc.Vec2 {
        if (ori == Oriented.UP)
            return current.add(cc.v2(0, Constants.ENTITY_EDGE / 2 - 5));
        else
            return this.DC(current, ori);
    }

    /**
     * 判断他在我的哪个方向
     * @param me 我的位置
     * @param him 他的位置
     * @param nowMe 我当前的朝向
     */
    public DIR(me: cc.Vec2, him: cc.Vec2, nowMe: Oriented): Oriented {
        let horDis = Math.abs(me.y - him.y);
        if (horDis > 10)
            return nowMe;
        if (me.x - him.y > 0)
            return Oriented.RIGHT;
        return Oriented.LEFT;
    }
}